//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.baosight.iplat4j.core.data.ibatis.sql.sqlmap.execution;

import com.baosight.iplat4j.core.FrameworkInfo;
import com.baosight.iplat4j.core.data.dao.util.SqlDaoUtil;
import com.baosight.iplat4j.core.data.sql.SQLEnhancer;
import com.baosight.iplat4j.core.data.sql.SQLEnhancerManager;
import com.baosight.iplat4j.core.exception.PlatException;
import com.baosight.iplat4j.core.log.xeye.PlatEye;
import com.baosight.iplat4j.core.log.xeye.entity.XEyeEntity;
import com.baosight.iplat4j.core.mock.MockPreparedStatement;
import com.baosight.iplat4j.core.security.dao.DaoSecurityManager;
import com.baosight.iplat4j.core.util.DateUtils;
import com.ibatis.sqlmap.client.SqlMapException;
import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;
import com.ibatis.sqlmap.engine.scope.ErrorContext;
import com.ibatis.sqlmap.engine.scope.RequestScope;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class SqlExecutor extends com.ibatis.sqlmap.engine.execution.SqlExecutor {
    private static final Logger logger = LogManager.getLogger(SqlExecutor.class);
    private static final String OPERATION_QUERY = "query";
    private static final String OPERATION_INSERT = "insert";
    private static final String OPERATION_UPDATE = "update";
    private static final String OPERATION_DELETE = "delete";

    public SqlExecutor() {
    }

    public int executeQueryCount(RequestScope request, Connection connection, String sql, Object[] parameters) throws Throwable {
        int count = 0;
        String stmtName = request.getStatement().getId();
        XEyeEntity xEyeEntity = this.initXEyeEntity(stmtName, "query", "0503");
        String sqlInfo = null;
        ErrorContext errorContext = request.getErrorContext();
        errorContext.setActivity("executing query");
        errorContext.setObjectId(sql);
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            String dbType = SqlHelper.getDataBaseType(connection);
            SqlHelper.setDataBaseLogInfo(connection, xEyeEntity);
            sql = this.addTenantCondition(connection, sql);
            sql = SqlHelper.getCountSql(sql, dbType);
            errorContext.setMoreInfo("Check the SQL Statement (preparation failed).");
            Integer rsType = request.getStatement().getResultSetType();
            if (rsType != null) {
                ps = connection.prepareStatement(sql, rsType, 1007);
            } else {
                ps = connection.prepareStatement(sql);
            }

            errorContext.setMoreInfo("Check the parameters (set parameters failed).");
            request.getParameterMap().setParameters(request, ps, parameters);
            errorContext.setMoreInfo("Check the statement (query failed).");
            sqlInfo = getExecuteSql(request, sql, parameters);
            xEyeEntity.setSql(sqlInfo);
            if (logger.isInfoEnabled()) {
                logger.info(sqlInfo);
            }

            rs = ps.executeQuery();
            if (rs != null && rs.next()) {
                count = rs.getInt("count_");
            }
        } catch (Throwable var30) {
            Throwable th = var30;
            String errorMsg = "";
            if (logger.isInfoEnabled()) {
                if (sqlInfo != null) {
                    logger.info(sqlInfo);
                } else {
                    logger.info(sql);
                    xEyeEntity.setSql(sql);
                }
            }

            if (th instanceof SqlMapException) {
                errorMsg = "There is no sql " + stmtName + "!";
                logger.error(errorMsg);
            } else {
                errorMsg = PlatException.getExceptionMsg(th);
                logger.error(errorMsg);
            }

            xEyeEntity.setErrorMsg(errorMsg);
            xEyeEntity.setStatus("-1");
            throw th;
        } finally {
            try {
                closeResultSet(rs);
            } finally {
                closeStatement(ps);
            }

            this.log(xEyeEntity);
        }

        return count;
    }

    private String addTenantCondition(Connection connection, String sql) {
        SQLEnhancer enhancer = SQLEnhancerManager.getSqlEnhancerThreadLocal();
        if (enhancer != null) {
            Map props = new HashMap();
            sql = enhancer.enhance(sql, SqlDaoUtil.getDbTypeAbbr(connection), props);
        }

        return sql;
    }

    public void executeQuery(RequestScope request, Connection conn, String sql, Object[] parameters, int skipResults, int maxResults, RowHandlerCallback callback, boolean autoLimit) throws Throwable {
        String stmtName = request.getStatement().getId();
        XEyeEntity xEyeEntity = this.initXEyeEntity(stmtName, "query", "0503");
        String sqlInfo = null;
        String dbType = SqlHelper.getDataBaseType(conn);
        SqlHelper.setDataBaseLogInfo(conn, xEyeEntity);
        ErrorContext errorContext = request.getErrorContext();
        errorContext.setActivity("executing query");
        errorContext.setObjectId(sql);
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            errorContext.setMoreInfo("Check the SQL Statement (preparation failed).");
            sql = this.addTenantCondition(conn, sql);
            if (DaoSecurityManager.isValidationEnabled()) {
                sql = SqlHelper.getAuthorizedSQL(stmtName, sql);
            }

            if (autoLimit) {
                sql = SqlHelper.getLimitSQL(dbType, sql, skipResults, maxResults);
            }

            if (FrameworkInfo.isAppendLogId()) {
                String traceId = PlatEye.getTraceId();
                if (traceId != null) {
                    sql = sql + "-- traceId[" + traceId + "]";
                }
            }


            //------------------------DB2改达梦关键字替换AOP------------------------
            sql=DB2ToDM(sql);

            Integer rsType = request.getStatement().getResultSetType();
            if (rsType != null) {
                ps = conn.prepareStatement(sql, rsType, 1007);
            } else {
                ps = conn.prepareStatement(sql);
            }

            Integer fetchSize = request.getStatement().getFetchSize();
            if (fetchSize != null) {
                ps.setFetchSize(fetchSize);
            } else {
                ps.setFetchSize(50);
            }

            errorContext.setMoreInfo("Check the parameters (set parameters failed).");
            request.getParameterMap().setParameters(request, ps, parameters);
            errorContext.setMoreInfo("Check the statement (query failed).");
            if (autoLimit) {
                SqlHelper.prepareParameter(dbType, parameters, skipResults, maxResults, ps);
            }

            sqlInfo = getExecuteSql(request, sql, parameters);
            xEyeEntity.setSql(sqlInfo);
            if (logger.isInfoEnabled()) {
                logger.info(sqlInfo);
            }

            ps.execute();
            rs = this.getFirstResultSet(ps);
            if (rs != null) {
                errorContext.setMoreInfo("Check the results (failed to retrieve results).");
                this.handleResults(request, rs, skipResults, maxResults, callback, dbType);
            }

//            while(true) {
//                if (ps.getMoreResults()) {
//                    continue;
//                }
//            }
        } catch (Throwable var34) {
            Throwable th = var34;
            String errorMsg = "";
            if (logger.isInfoEnabled()) {
                if (sqlInfo != null) {
                    logger.info(sqlInfo);
                } else {
                    logger.info(sql);
                    xEyeEntity.setSql(sql);
                }
            }

            if (th instanceof SqlMapException) {
                errorMsg = "There is no sql " + stmtName + "!";
                logger.error(errorMsg);
            } else {
                errorMsg = PlatException.getExceptionMsg(th);
                logger.error(errorMsg);
            }

            xEyeEntity.setErrorMsg(errorMsg);
            xEyeEntity.setStatus("-1");
            throw th;
        } finally {
            try {
                closeResultSet(rs);
            } finally {
                closeStatement(ps);
            }

            this.log(xEyeEntity);
        }

    }

    private void handleResults(RequestScope request, ResultSet rs, int offset, int limit, RowHandlerCallback callback, String dbType) throws SQLException {
        try {
            request.setResultSet(rs);
            ResultMap resultMap = request.getResultMap();
            if (resultMap != null) {
                int i;
                if (offset > 0 && !SqlHelper.supportOffset(dbType)) {
                    if (rs.getType() != 1003) {
                        rs.absolute(offset);
                    } else {
                        for(i = 0; i < offset && rs.next(); ++i) {
                        }
                    }
                }

                for(i = 0; i < limit && rs.next(); ++i) {
                    Object[] columnValues = resultMap.resolveSubMap(request, rs).getResults(request, rs);
                    callback.handleResultObject(request, columnValues, rs);
                }
            }
        } finally {
            request.setResultSet((ResultSet)null);
        }

    }

    private ResultSet getFirstResultSet(Statement stmt) throws SQLException {
        do {
            ResultSet rs = stmt.getResultSet();
            if (rs != null) {
                return rs;
            }
        } while(stmt.getMoreResults() || stmt.getUpdateCount() != -1);

        return null;
    }

    private static void closeStatement(PreparedStatement ps) {
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException var2) {
            }
        }

    }

    private static void closeResultSet(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException var2) {
            }
        }

    }

    public int executeUpdate(RequestScope request, Connection conn, String sql, Object[] parameters) throws SQLException {
        String stmtName = request.getStatement().getId();
        XEyeEntity xEyeEntity = null;
        String sqlInfo = null;
        String operation = null;
        sql = this.addTenantCondition(conn, sql);
        if (sql.toLowerCase().contains("insert ")) {
            operation = "insert";
            xEyeEntity = this.initXEyeEntity(stmtName, "insert", "0500");
        } else if (sql.toLowerCase().contains("update ")) {
            operation = "update";
            xEyeEntity = this.initXEyeEntity(stmtName, "update", "0502");
        } else if (sql.toLowerCase().contains("delete ")) {
            operation = "delete";
            xEyeEntity = this.initXEyeEntity(stmtName, "delete", "0501");
        }

        SqlHelper.setDataBaseLogInfo(conn, xEyeEntity);

        int var16;
        try {
            sqlInfo = getExecuteSql(request, sql, parameters);
            xEyeEntity.setSql(sqlInfo);
            if (logger.isInfoEnabled()) {
                logger.info(sqlInfo);
            }

            if (operation != null && !operation.equals("insert")) {
                this.verifySqlParamCondition(operation, stmtName, xEyeEntity, sql);
            }

            var16 = super.executeUpdate(request, conn, sql, parameters);
        } catch (Throwable var14) {
            Throwable th = var14;
            String errorMsg = "";
            if (logger.isInfoEnabled()) {
                if (sqlInfo != null) {
                    logger.info("current  sql:" + sqlInfo);
                } else {
                    logger.info("current  sql:" + sql);
                    xEyeEntity.setSql(sql);
                }
            }

            if (th instanceof SqlMapException) {
                errorMsg = "There is no sql " + stmtName + "!";
                logger.error(errorMsg);
            } else {
                errorMsg = PlatException.getExceptionMsg(th);
                logger.error(errorMsg);
            }

            xEyeEntity.setErrorMsg(errorMsg);
            xEyeEntity.setStatus("-1");
            try {
                throw th;
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        } finally {
            this.log(xEyeEntity);
        }

        return var16;
    }

    public void executeQuery(RequestScope request, Connection conn, String sql, Object[] parameters, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException {
        String stmtName = request.getStatement().getId();
        XEyeEntity xEyeEntity = this.initXEyeEntity(stmtName, "query", "0503");
        SqlHelper.setDataBaseLogInfo(conn, xEyeEntity);
        String sqlInfo = null;
        sql = this.addTenantCondition(conn, sql);

        try {
            sqlInfo = getExecuteSql(request, sql, parameters);
            xEyeEntity.setSql(sqlInfo);
            if (logger.isInfoEnabled()) {
                logger.info(sqlInfo);
            }
            //DB2转换达梦sql
            sql=DB2ToDM(sql);
            super.executeQuery(request, conn, sql, parameters, skipResults, maxResults, callback);
        } catch (Throwable var16) {
            Throwable th = var16;
            String errorMsg = "";
            if (logger.isInfoEnabled()) {
                if (sqlInfo != null) {
                    logger.info("current  sql:" + sqlInfo);
                } else {
                    logger.info("current  sql:" + sql);
                    xEyeEntity.setSql(sql);
                }
            }

            if (th instanceof SqlMapException) {
                errorMsg = "There is no sql " + stmtName + "!";
                logger.error(errorMsg);
            } else {
                errorMsg = PlatException.getExceptionMsg(th);
                logger.error(errorMsg);
            }

            xEyeEntity.setErrorMsg(errorMsg);
            xEyeEntity.setStatus("-1");
            try {
                throw th;
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        } finally {
            this.log(xEyeEntity);
        }

    }

    public int executeUpdateProcedure(RequestScope request, Connection conn, String sql, Object[] parameters) throws SQLException {
        String stmtName = request.getStatement().getId();
        XEyeEntity xEyeEntity = null;
        String sqlInfo = null;
        String operation = null;
        sql = this.addTenantCondition(conn, sql);
        if (sql.toLowerCase().contains("insert ")) {
            operation = "insert";
            xEyeEntity = this.initXEyeEntity(stmtName, "insert", "0500");
        } else if (sql.toLowerCase().contains("update ")) {
            operation = "update";
            xEyeEntity = this.initXEyeEntity(stmtName, "update", "0502");
        } else if (sql.toLowerCase().contains("delete ")) {
            operation = "delete";
            xEyeEntity = this.initXEyeEntity(stmtName, "delete", "0501");
        }

        SqlHelper.setDataBaseLogInfo(conn, xEyeEntity);

        int var16;
        try {
            sqlInfo = getExecuteSql(request, sql, parameters);
            xEyeEntity.setSql(sqlInfo);
            if (logger.isInfoEnabled()) {
                logger.info(sqlInfo);
            }

            if (operation != null && !operation.equals("insert")) {
                this.verifySqlParamCondition(operation, stmtName, xEyeEntity, sql);
            }

            var16 = super.executeUpdateProcedure(request, conn, sql, parameters);
        } catch (Throwable var14) {
            Throwable th = var14;
            String errorMsg = "";
            if (logger.isInfoEnabled()) {
                if (sqlInfo != null) {
                    logger.info("current  sql:" + sqlInfo);
                } else {
                    logger.info("current  sql:" + sql);
                    xEyeEntity.setSql(sql);
                }
            }

            if (th instanceof SqlMapException) {
                errorMsg = "There is no sql " + stmtName + "!";
                logger.error(errorMsg);
            } else {
                errorMsg = PlatException.getExceptionMsg(th);
                logger.error(errorMsg);
            }

            xEyeEntity.setErrorMsg(errorMsg);
            xEyeEntity.setStatus("-1");
            try {
                throw th;
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        } finally {
            this.log(xEyeEntity);
        }

        return var16;
    }

    public void executeQueryProcedure(RequestScope request, Connection conn, String sql, Object[] parameters, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException {
        String stmtName = request.getStatement().getId();
        XEyeEntity xEyeEntity = this.initXEyeEntity(stmtName, "query", "0503");
        String sqlInfo = null;
        SqlHelper.setDataBaseLogInfo(conn, xEyeEntity);
        sql = this.addTenantCondition(conn, sql);

        try {
            sqlInfo = getExecuteSql(request, sql, parameters);
            xEyeEntity.setSql(sqlInfo);
            if (logger.isInfoEnabled()) {
                logger.info("currentQueryProcedure sql:" + sqlInfo);
            }

            super.executeQueryProcedure(request, conn, sql, parameters, skipResults, maxResults, callback);
        } catch (Throwable var16) {
            Throwable th = var16;
            String errorMsg = "";
            if (logger.isInfoEnabled()) {
                if (sqlInfo != null) {
                    logger.info("currentQueryProcedure sql:" + sqlInfo);
                } else {
                    logger.info("currentQueryProcedure sql:" + sql);
                    xEyeEntity.setSql(sql);
                }
            }

            if (th instanceof SqlMapException) {
                errorMsg = "There is no sql " + stmtName + "!";
                logger.error(errorMsg);
            } else {
                errorMsg = PlatException.getExceptionMsg(th);
                logger.error(errorMsg);
            }

            xEyeEntity.setErrorMsg(errorMsg);
            xEyeEntity.setStatus("-1");
            try {
                throw th;
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
        } finally {
            this.log(xEyeEntity);
        }

    }

    private void verifySqlParamCondition(String operation, String name, XEyeEntity xEyeEntity, String sql) {
        String sqlValidateMsg = "";
        if (!"<empty>".equals(sql) && StringUtils.isNotEmpty(sql)) {
            String sqlValidate = sql.toUpperCase();
            sqlValidate = sqlValidate.replaceAll("\\s", "");
            int whereConditionIndex = sqlValidate.indexOf("WHERE");
            if (whereConditionIndex >= 0) {
                String interceptWhereSql = sqlValidate.substring(whereConditionIndex + 5, sqlValidate.length());
                if (StringUtils.isNotEmpty(interceptWhereSql) && interceptWhereSql.indexOf("1=1") >= 0) {
                    String interceptOneAndOneSql = interceptWhereSql.substring(interceptWhereSql.indexOf("1=1") + 3, interceptWhereSql.length());
                    if (StringUtils.isEmpty(interceptOneAndOneSql)) {
                        sqlValidateMsg = operation + "操作失败，sql语句" + name + "，不允许以WHERE 1=1结束后不带条件";
                    }
                }
            } else {
                sqlValidateMsg = operation + "操作失败，sql语句" + name + "，不允许不带WHERE条件";
            }
        } else {
            sqlValidateMsg = operation + "操作失败，sql语句" + name + "为空";
        }

        if (StringUtils.isNotEmpty(sqlValidateMsg)) {
            throw new PlatException(sqlValidateMsg);
        }
    }

    private XEyeEntity initXEyeEntity(String name, String operate, String logTypeId) {
        XEyeEntity xEyeEntity = new XEyeEntity(logTypeId);
        xEyeEntity.setStartTime(DateUtils.curDateMselStr17());
        xEyeEntity.setSqlMapName(name);
        xEyeEntity.setInvokeInfo(" Dao operate [" + operate + "] sqlmap name [" + name + "] ,result:");
        return xEyeEntity;
    }

    private XEyeEntity initXEyeEntity(String name, String operate, String logTypeId, int offset, int limit) {
        XEyeEntity xEyeEntity = new XEyeEntity(logTypeId);
        xEyeEntity.set("x_sq_o", offset);
        xEyeEntity.set("x_sq_l", limit);
        xEyeEntity.setStartTime(DateUtils.curDateMselStr17());
        xEyeEntity.setSqlMapName(name);
        xEyeEntity.setInvokeInfo(" Dao operate [" + operate + "] sqlmap name [" + name + "] ,result:");
        return xEyeEntity;
    }

    private void log(XEyeEntity xEyeEntity) {
        xEyeEntity.setEndTime(DateUtils.curDateMselStr17());
        xEyeEntity.calculateCost();
        if (Integer.valueOf(xEyeEntity.getStatus()) > -1) {
            xEyeEntity.setInvokeInfo(xEyeEntity.getInvokeInfo() + "success!");
        } else {
            xEyeEntity.setInvokeInfo(xEyeEntity.getInvokeInfo() + "error!");
        }

        PlatEye.linkTrace(xEyeEntity);
    }

    public static String getExecuteSql(RequestScope request, String sql, Object[] parameters) throws SQLException {
        ParameterMap parameterMap = request.getParameterMap();
        MockPreparedStatement ps = new MockPreparedStatement(sql);
        parameterMap.setParameters(request, ps, parameters);
        return ps.getSql();
    }

    /**
     * DB2改达梦关键字替换AOP
     * @param sql
     * @return
     */
    public String DB2ToDM(String sql){
        //------------------------------------------------
        if (sql.indexOf("CONTEXT")>0 || sql.indexOf("context")>0){
            //如果已修改的 CONTEXT带双引号 放行
            if (sql.indexOf("\"CONTEXT\"")>0 || sql.indexOf("\"context\"")>0){
            }else{
                //添加双引号
                sql = sql.replaceAll("CONTEXT", "\"CONTEXT\"");}
        }

        //-----------IPLAT4J.TEDFA10表修改=》缺少字段 Start
        if (sql.indexOf("TEDFA10")>0) {
            if (sql.indexOf("CUSTOM_CNAME") > 0 || sql.indexOf("custom_cname") > 0) {
                sql = sql.replaceAll("CUSTOM_CNAME", "'CUSTOM_CNAME'");
            }
            if (sql.indexOf("COLOR") > 0 || sql.indexOf("custom_cname") > 0) {
                sql = sql.replaceAll("COLOR", "'COLOR'");
            }
            if (sql.indexOf("SHOW_FLAG") > 0 || sql.indexOf("showFlag") > 0) {
                sql = sql.replaceAll("SHOW_FLAG", "'SHOW_FLAG'");
            }
            if (sql.indexOf("FORM_GROUP") > 0 || sql.indexOf("formGroup") > 0) {
                sql = sql.replaceAll("FORM_GROUP", "'FORM_GROUP'");
            }
        }
        //-----------IPLAT4J.TEDFA10表修改=》缺少字段 End
        return sql.replaceAll(" SIGNED", " INTEGER");
    }
}
